# @Time : 2024-10-17 13:42
# @Author : Fioman 
# @Phone : 13149920693
"""
任何使用单引号或者是双引号,或者是三个单引号,或者是三个双引号包裹起来的内容都是字符串.使用len()方法
可以获取字符串的长度.在Python中当字符串的长度为1时可以表示为字符,但是它本质上还是字符串,就是Python
没有字符这种概念了,但是你是可以获取一个数据的字符形式的,通过chr()
"""
# region 1. 字符串的创建
letter = "Fioman"
print(f"letter: {letter} ,lenth:  {len(letter)}")
str02 = '单引号字符串'
print(f"str02: {str02} ,lenth:  {len(str02)}")
str03 = 'A'
print(f"str03: {str03} ,lenth:  {len(str03)},type: {type(str03)}")
char04 = chr(100)  # 虽然是转换为字符,但是其最后转换的类型还是字符串
print(f"char04: {char04} ,lenth:  {len(char04)}, type:{type(char04)}")
str04 = '''
我是单引号的多行字符串,
我支持换行
    我也支持空格
'''
print(f"str04: {str04} ,lenth:  {len(str04)}")
str05 = """
我是双引号的多行字符串,
我也支持换行
        并且也支持空格
        
        还支持空行
"""
print(f"str05: {str05} ,lenth:  {len(str05)}")
# endregion

# region 2. 字符串串联
# 1. 使用 + 号运算符将内容串联
name = "Fioman"
age = 18
gender = "男"
info = "姓名: " + name + " 年龄: " + str(age) + " 性别: " + gender
print("joint by + : " + info)

# 使用join方法,可以将可迭代对象中的字符串拼接起来,通常比+更加的高效,尤其是拼接
# 多个字符的时候
info = " ".join(["姓名: ", name, " 年龄: ", str(age), "性别: ", gender])
print("joint by join:", info)
# 使用%格式化
info = "姓名: %s 年龄: %d 性别: %s" % (name, age, gender)
print("joint by %: ", info)
# 使用str.format
info = "姓名: {},年龄: {},性别: {}".format(name, age, gender)
print("joint by format: {}".format(info))
# 使用f-string
info = f"姓名:{name},年龄: {age},性别: {gender}"
print(f"joint by f-string: {info}")
# 使用StringIO 适合大量字符串的拼接
from io import StringIO

buffer = StringIO()
buffer.write("姓名: ")
buffer.write(name)
buffer.write(" 年龄: ")
buffer.write(str(age))
buffer.write(" 性别: ")
buffer.write(gender)
info = buffer.getvalue()
print(f"joint by StringIO: {info}")
# endregion

# region 3. 字符串中的转义序列
# \n: 换行 \t: 制表符(4个空格) \\: 反斜杠 \': 单引号  \" 双引号
print("我希望我能成为一个好的Pythoner\n")  # 换行
print("第一行\t 方法\t 是否有效")  # 制表符
print("第二行\t 练习\t 有效")  # 制表符
print('输出反斜杠: (\\)')
print("输出单引号: (\')")
print("输出双引号: (\")")
print("输出带双引号的字符串: \"我是带双引号的字符串\"")
print("输出带单引号的字符串: \'我是带单引号的字符串\'")

# endregion

# region 4. 字符串是字符序列,可以通过索引访问,还可以通过解压的方式进行序列赋值
name = "Fioman"
firstLetter = name[0]
lastLetter = name[-1]  # 通过负索引进行访问
print(firstLetter, lastLetter)
# 序列赋值,其他不要,只获取第一个和最后一个,中间使用的不定长占位符
firstLetter, *_, lastLetter = name
print(firstLetter, lastLetter)
# 通过序列赋值只获取中间的三个值,这样得到的结果是一个字符列表
_, *middleLetter, _ = name  # ['i', 'o', 'm', 'a']
print("middleLetter: {}".format(middleLetter))
# 字符串切片,这个比较常用和实用,获取字符串的子串,通过切片的方式
firstThree = name[:3]  # 从0开始,直到3,不包括3 0,1,2
print("firstThree: {}".format(firstThree))
lastThree = name[-3:]  # 最后三个
print("lastThree: {}".format(lastThree))
midThree = name[2:5]
print("midThree: {}".format(midThree))
# 字符串反转
nameReverse = name[::-1]
print("nameReverse: {}".format(nameReverse))
# 使用reversed()函数,reversed()返回一个反向迭代器,需要通过join一起获取反转字符串
nameReverse = ''.join(reversed(name))
print("nameReverse: {}".format(nameReverse))
# 反向切片,比如我要获取Fioman 的 nam 如何获取呢 反向切片
nameSlice = name[-1:-4:-1]
print("nameSlice: {}".format(nameSlice))

# 或者你要获取Fioman 的 oiF就是倒着切的时候,只要把步长改为负数就可以了
nameSlice = name[2::-1]
print("nameSlice: {}".format(nameSlice))

# 切片的时候还可以设置步长跳过
nameSlice = name[::2]
print("nameSlice: {}".format(nameSlice))
# endregion

# region 5. 字符串中常用的方法
# 1) capitalize() 第一个字符转换为大写,常用的快捷键为Ctrl + Shift + U 大小写切换
title = "study python"
print(title.capitalize())
# 2) count() 返回字符串中子字符串出现的次数count(子字符串,start=0,end=..)默认是整个字符串
title = "I just want to tell you what you want to do,I help you!"
print(title.count("you", 0, 30))
print(title.count("you", 0, 20))
print(title.count("you"))
# 3) endswith() 判断字符串是否以特定的字符串结尾,返回True或者False
fileName = "file_test.txt"
print(fileName.endswith(".txt"))
print(fileName.endswith(".pdf"))
# 4) startswith() 判断字符串是否以特定的字符串开始,返回True或者False
print(fileName.startswith("file_"))
print(fileName.startswith("ile"))
# 5) find() 返回子字符串第一次出现的索引,如果没有出现则返回-1
youIndex = title.find("you")
print(f"youIndex : {youIndex}")
yourIndex = title.find("your")
print(f"yourIndex : {yourIndex}")  # -1
# 6) rfind() 从后面往前找,找第一次出现的索引
youIndexLast = title.rfind("you")
print(f"youIndexLast : {youIndexLast}")
# 7) index() 返回子字符串的最小索引,如果没有找到引发valueError
subString = "you"
print("subStringIndex: ", title.index(subString))
# subString = "your"
# print(f"subStringIndex : {title.index(subString)}")  # 引发异常valueError
# 8) rindex() 返回子字符串的最大索引,也就是从后往前找
print("subStringIndexLast: {}".format(title.rindex(subString)))
# 9) isalnum() 判断字符串是否是字母数字字符,只能包含字母和数字,不能包含其他比如汉字,空格特殊字符
strA = "123456"
print(strA.isalnum())  # True
strB = "我是123"  # Fasle ,不能有汉字
print(strB.isalpha())
strC = "your age is 30"  # False 不能有空格
print(strC.isalnum())
strD = "yourageis30"
print(strD.isalnum())  # True
# 10) isalpha(): 判断字符串是否都是字母字符(a-z and A-Z)
strA = "123Abc"
strB = "abc_"
strC = "AaZa"
strD = "_A"
print(strA.isalpha(), strB.isalpha(), strC.isalpha(), strD.isalpha())
# 11) isdeicimal() 判断字符串中所有的字符是否都是十进制的数字,不包含Unicode字符
strA = "\u00B2"  # unicode字符,不是十进制
strB = "12.3"  # 字符
strC = "123"  # True
strD = "12 3"  # 含有空格
print(strA.isdecimal(), strB.isdecimal(), strC.isdecimal(), strD.isdecimal())  # False,False,True,False
# 12) isdigit() 判断字符串中所有的字符是否都是数字(0-9还有一些其他表示数字的Unicode字符)
print(strA.isdigit(), strB.isdigit(), strC.isdigit(), strD.isdigit())  # True,False,True,False
# 13) isnumeric() 判断字符串中是否都是数字或者是和数字相关(和isdigit()类似返回更广,比如1/2)
num = "10"
print(f"{num.isnumeric()}")  # True
num = "\u00BD"  # 1/2
print(f"num: {num},{num.isnumeric()}")  # 1/2 True
num = "12.3"
print(f"num: {num},{num.isnumeric()}")  # False 是小数
# 14)  isidentifier() 判断是否是有效的标识符- 检查字符串时候是有效的变量名
valName = "1num"
print(f"valName: {valName},{valName.isidentifier()}")
valName = "num01"
print(f"valName: {valName},{valName.isalnum()}")
# 15) islower() isupper() 判断字符串中是否全部是小写/大写
strVal = "I am very happy"
print(f"{strVal.islower()}")  # False
print(f"{strVal.isupper()}")  # False
# 16) join() 返回连接后的字符串,用固定的字符进行连接
listVal = ["1", "2", "3", "4"]
listVal02 = [1, 2, 3, 4]
result = "abc".join(listVal)
print("result: {}".format(result))
listVal02Str = str(listVal02)
print(listVal02Str)  # [1, 2, 3, 4]
result = "x".join(str(listVal02))  # '[1,2,3,4]' 相当于是将这个字符串重新连接了一下返回
print("result: {}".format(result))  # [x1x,x x2x,x x3x,x x4x]
# 17) strip() 删除从字符串开头和结尾的所有的给定字符,默认不给就是删除空格,注意是开头和结尾
strVal = "I am very happyyy"
print(strVal.strip("pyI"))  # am very ha 开头也会删除I py在结尾,结尾先找到y,然后删除完再去找p所以py都
# 会被删除掉
print(strVal.strip(''))
# 18) replace() 用给定的字符串替换子字符串,如果子字符串不存在呢
title = "Do your best"
titleNew = title.replace("your", "my")
print("titleNew: {}".format(titleNew))
titleNew = title.replace("better", "best")  # 如果要替换的子串不存在,什么也不做,不报错
print("titleNew: {}".format(titleNew))
# 19) split()只用特定的字符串来拆分字符串,如果没有提供就使用空格
strVal = "姓名: Fioman, 年龄:24, 性别:男"
splitSpace = strVal.split()  # ['姓名:', 'Fioman,', '年龄:24,', '性别:男']
print(f"splitSpace: {splitSpace}")
splitA = strVal.split(":")
print(f"splitA: {splitA}")
# 20) title() 返回标题大小写的字符串,每个单词首字母大写
title = "i  am happy to tell you something"
print(f"title = {title.title()}")
# 21) swapcase() 将所有的大写字符串转换为小写字符串,小写转换为大写
title = title.title()
print(f"title swapcase: {title.swapcase()}")
# endregion

# region 6. 字符串训练
jointed = "I" + "will" + "study" + "hard"
print(f"jointed: {jointed}")
jointed = " ".join(["Coding", "For", "All"])
print(f"jointed: {jointed}")
company = "Coding For All"
print(f"company: {company},len: {len(company)}")
print(f"upper() : {company.upper()}")
print(f"lower() : {company.lower()}")
print(f"capitalize() : {company.capitalize()}")
print(f"title(): {company.title()}")
print(f"swapcase(): {company.swapcase()}")
firstWord = company[:len("Coding")]
print(f"firstWord: {firstWord}")
# 如果不存在,会引发异常
try:
    codingIndex = company.index("Coding")
except Exception as e:
    codingIndex = -1
    print(str(e))
print(f"是否存在: True, index = {codingIndex}")

# 可以使用find,如果不存在就只会返回-1
codingIndex = company.find("Coding")
if codingIndex != -1:
    print(True)
else:
    print(False)
companyRepalce = company.replace("Coding", "Pyhton")
print("newCompany: {}".format(companyRepalce))
splitStr = company.split(" ")
print(f"splitStr: {splitStr}")
strVal = "Facebook,Google,Microsoft,Apple,IBM,Oracle,Amazon"
print(f"splitVal: {strVal.split(',')}")
print(f"index0 val = {strVal[0]}")
print(f"lastIndex = {len(strVal)}")
print(f"index of 10 = {strVal[10]}")
# 创建缩写
res = "".join([x[0] for x in strVal.split(",")])
print("缩写: {}".format(res))
print("strVal: {}".format(strVal))
firstIndexOfC = strVal.index('c')
print("index of c first: {}".format(firstIndexOfC))
print("index of b first: {}".format(strVal.index('b')))
print("index of c last: {}".format(strVal.rfind('c')))
strVal = "You cannot end a sentence with because because because is a conjunction'"
firstBecauseIndex = strVal.find("because")
print(f"firstBecauseIndex: {firstBecauseIndex}")
lastBecauseIndex = strVal.rfind("because")
print(f"lastbecauseIndex: {lastBecauseIndex}")
# 删除字符串because,通过replace来删除,将其替换为空字符串即可
res = strVal.replace("because", "")
print("删除后的结果: {}".format(res))
print("strVal是否以You 开头: {}".format(strVal.startswith("You")))
print("strVal是否以bction结尾: {}".format(strVal.endswith("bction")))

val = "1_a"
val2 = "_a"
print(val.isidentifier())
print(val2.isidentifier())
print("I am enjoying this challenge. \nI just wonder what is next.")
print("Name\tAge\tCountry\tCity\t")
print("Fioman\t250\tFinland\tShenzhen\t")
radius = 10
area = 3.14 * radius ** 2
print(f"面积是: {int(area)}")
a = 8
b = 6
print(f"{a} + {b} = {a + b}")
print(f"{a} - {b} = {a - b}")
print(f"{a} * {b} = {a * b}")
print(f"{a} / {b} = {a // b}")
print(f"{a} % {b} = {a % b}")
print(f"{a} // {b} = {a // b}")
print(f"{a} ** {b} = {a ** b}")
# endregion
